<?php
/*
 *  This file is part of Urd.
 *
 *  Urd is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  Urd is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. See the file "COPYING". If it does not
 *  exist, see <http://www.gnu.org/licenses/>.
 *
 * $LastChangedDate: 2008-12-20 23:08:45 +0100 (Sat, 20 Dec 2008) $
 * $Rev: 345 $
 * $Author: gavinspearhead $
 * $Id: thread.php 345 2008-12-20 22:08:45Z gavinspearhead $
 */


// This is an include-only file:
if (!defined('ORIGINAL_PAGE')) die('This file cannot be accessed directly.');


$paththr = realpath(dirname(__FILE__));
require_once "$paththr/../functions/autoincludes.php";
require_once "$paththr/../functions/functions.php";


class thread {
	private $pid;
	private $action;
	private $end_status;  // Use DOWNLOAD_ACTIVE etc

	function __construct ($pid, action $action)
	{
		assert(is_numeric($pid));
		$this->pid = (int) $pid;
		$this->action = $action;
		$this->action->set_start_time();
		$this->end_status = DOWNLOAD_ACTIVE;
	}
    function get_pid() 
    {
        return $this->pid;
    }
    function &get_action() 
    { 
        return $this->action;
    }
    function set_status($stat) 
    { 
        $this->end_status = $stat;
    }
    function get_status() 
    { 
        return $this->end_status;
    }
}


define ('DUMMY_THREAD', NULL);

class thread_list {
	private $threads;

    function __construct () 
    {
        $this->threads = array(); 
    }
    function size() 
    {
        return count($this->threads); 
    }
    function add(thread $thread) 
    { 
        $this->threads[$thread->get_pid()] = $thread; 
    }
	function add_thread(DatabaseConnection $db, thread $thread, $server_id) 
	{
		assert(is_numeric($server_id));
		$thread->get_action()->set_active_server($server_id);
		$pid = $thread->get_pid();
		if (isset($this->threads[$pid]))
			throw new exception ('PID already exists');
		$this->threads[$pid] = $thread; 
	}
	function add_dummy_thread($pid)
	{
		if (!isset ($this->threads[$pid]))
			$this->thread[$pid] = DUMMY_THREAD;
		else
			throw new exception ('PID already exists');
	}
	function &get_thread($pid) 
	{ 
		assert(is_numeric($pid));
		if (!isset($this->threads[$pid]))
			throw new exception ("Thread not found (pid $pid)", ERR_THREAD_NOT_FOUND);
		return $this->threads[$pid]; 
	}
	function has_thread($pid) 
	{ 
		assert(is_numeric($pid));
		return isset($this->threads[$pid]);
	}

	function get_threads() 
	{ 
		$threads = array();
		foreach( $this->threads as $t) {
			if ($t === DUMMY_THREAD) continue;
			$a = $t->get_action();
			$thread['id'] = $a->get_id();
			$thread['pid'] = $t->get_pid();
			$thread['username'] = $a->get_username();
			$thread['command'] = $a->get_command();
			$thread['args'] = $a->get_args();
			$thread['paused'] = $a->is_paused();
			$thread['queue_time'] = $a->get_queue_time();
			$thread['start_time'] = $a->get_start_time();
			$thread['server'] = $a->get_active_server();
			$threads[] = $thread;
		}

		return $threads;
	}
	function delete_thread(DatabaseConnection $db, $pid, $store=FALSE)
	{
		assert(is_numeric($pid));
		if (!isset($this->threads[$pid]))
			throw new exception ("Thread not found (pid $pid)", ERR_THREAD_NOT_FOUND);
		$thread = $this->threads[$pid];
		if($thread == DUMMY_THREAD) 
			return array(NULL, 0, 0);
		$dbid = $thread->get_action()->get_dbid();
		$status = NULL;
		$stat_code = $thread->get_status();
		
		if ($stat_code == DOWNLOAD_CANCELLED)
			$status = QUEUE_CANCELLED;
		else if ($stat_code == DOWNLOAD_PAUSED)
			$status = QUEUE_PAUSED;
		else if ($stat_code == DOWNLOAD_FINISHED)
			$status = QUEUE_FINISHED;
		else if ($stat_code == DOWNLOAD_ERROR)
			$status = QUEUE_FAILED;
		else if ($stat_code == DOWNLOAD_STOPPED)
		       $status = QUEUE_QUEUED;	
		if ($status !== NULL) 
			update_queue_status ($db, $dbid, $status, 0);
			
		$item = $thread->get_action();
		$server_id = $item->get_active_server();
		$item->clear_server($store);
		unset($this->threads[$pid]);
		return array ($item, $server_id, $stat_code);
	}
	function delete(DatabaseConnection $db, $pid)
	{
		assert(is_numeric($pid));
		echo_debug('-= OLD FUNCTION... DO NOT USE =-', 255);
		return $this->delete_thread($db, $pid, FALSE);
	}
	function get_pid($action_id)
	{
		assert(is_numeric($action_id));
		foreach($this->threads as $t) {
            if ($t === DUMMY_THREAD) 
                continue;
			if ($t->get_action()->get_id() == $action_id)
				return $t->get_pid();
		}
		throw new exception ('Thread not found', ERR_THREAD_NOT_FOUND);
	}
	function get_pid_cmd($cmd, $arg)
	{
		$pids = array();
		foreach($this->threads as $k=>$t) {
            if ($t === DUMMY_THREAD) 
                continue;
			$a = $t->get_action();
			if ($a->is_equal($cmd, $arg))
				$pids[] = $t->get_pid();
		}
		return $pids;
	}
	function has_equal(action $a)
	{
		foreach($this->threads as $t) {
			if ($t === DUMMY_THREAD) continue;
			if ($t->get_action()->is_equal($a->get_command_code(), $a->get_args()))
				return TRUE;
		}
		return FALSE;
	}
	function get_all_pids($username)
	{
		$pids = array();
		foreach($this->threads as $t) {
			if ($t === DUMMY_THREAD) continue;
			if ($t->get_action()->match_username($username))
				$pids[] = $t->get_pid();
		}
		return $pids;
	}
}


?>
